package com.imooc.canal;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.google.gson.Gson;
import com.imooc.base.BaseInfoProperties;
import com.imooc.pojo.DataDictionary;
import com.imooc.utils.GsonUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import top.javatool.canal.client.annotation.CanalTable;
import top.javatool.canal.client.handler.EntryHandler;
import java.util.ArrayList;
import java.util.List;

/**
 * @author liansen
 * @create 04-14-14:54
 * EntryHandler<DataDictionary> 指定表关联的实体对象
 */
@CanalTable("data_dictionary")
@Component
public class DataDictCanalHelper extends BaseInfoProperties implements EntryHandler<DataDictionaryCO>  {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final String DATA_DICTIONARY = REDIS_DATA_DICTIONARY_ITEM_LIST + ":";

    /**
     * 因为数据字典中的数据很多，所以redis中比如有存了三个人员规模数据了，
     * 数据库又新增了一条人员规模，所以要判断一下redis中存不存在人员规模数据，
     * 如果不存在，则将监听到的数据加进去即可;
     * 如果存在，则在redis中原来的数据基础上添加进监听到的数据即可;
     * @param dataDictionary
     */
    @Override
    public void insert(DataDictionaryCO dataDictionary) {
        //这里能拿到数据库中新增了的数据
        System.out.println("插入: " + dataDictionary);
        String key = DATA_DICTIONARY + dataDictionary.getType_code();
        String jsonStr = redisTemplate.opsForValue().get(key);
        List<DataDictionary> list  = null;
        if(StringUtils.isBlank(jsonStr)){
            list = new ArrayList<>();
        }else {
            //如果存在，则在redis中原来的数据基础上添加进去即可;
            /**
             * redisTemplate.opsForValue().set(key, new Gson().toJson(dataDictionary));
             * 直接像上面这样写会有问题，因为key一样, 所以后来的数据会覆盖之前原有的数据,
             * 所以先把redis中之前存在数据转成list,将新增的数据加入list中，最后把完整的list放入redis即可;
             */
            list = GsonUtils.stringToListAnother(jsonStr, DataDictionary.class);
        }
        //第一次加数据是CO类型,这里会转成DataDictionary类型存进redis,所以下次再加的时候,
        // 将redis中的字符串转成list<DataDictionary>就不会出错了
        list.add(convert(dataDictionary));
        redisTemplate.opsForValue().set(key, GsonUtils.object2String(list));
    }

    public DataDictionary convert(DataDictionaryCO dataDictionaryCO){
        DataDictionary dataDic = new DataDictionary();
        BeanUtils.copyProperties(dataDictionaryCO, dataDic);
        dataDic.setTypeCode(dataDictionaryCO.getType_code());
        dataDic.setTypeName(dataDictionaryCO.getType_name());
        dataDic.setItemKey(dataDictionaryCO.getItem_key());
        dataDic.setItemValue(dataDictionaryCO.getItem_value());
        return dataDic;
    }

    @Override
    public void update(DataDictionaryCO before, DataDictionaryCO after) {
        System.out.println("更新前: " + before);
        System.out.println("更新后: " + after);

        String key = DATA_DICTIONARY + after.getType_code();
        String redisJson = redisTemplate.opsForValue().get(key);
        if(StringUtils.isBlank(redisJson)){
            //什么都不用做
        }else {
            List<DataDictionary> list = GsonUtils.stringToListAnother(redisJson, DataDictionary.class);
            for(DataDictionary dataDictionary : list){
                if(dataDictionary.getId().equals(after.getId())){
                    list.remove(dataDictionary);
                    list.add(convert(after));
                    break;
                }
            }
            redisTemplate.opsForValue().set(key, new Gson().toJson(list));
        }
    }

    @Override
    public void delete(DataDictionaryCO dataDictionary) {
        System.out.println("删除: " + dataDictionary);

        String key = DATA_DICTIONARY + dataDictionary.getType_code();
        //通过key,判断redis中有没有对应的数据
        String redisJson = redisTemplate.opsForValue().get(key);
        List<DataDictionary> list = null;
        if(StringUtils.isBlank(redisJson)){
            //如果不存在，啥也不用做
        }else {
            list = GsonUtils.stringToListAnother(redisJson, DataDictionary.class);
            for(DataDictionary dic : list){
                if(dic.getId().equals(dataDictionary.getId())){
                    list.remove(dic);
                    //如果不加break,会因为在foreach中删除集合元素，导致并发修改异常;或者可以使用普通fori循环
                    break;
                }
            }
            redisTemplate.opsForValue().set(key, new Gson().toJson(list));
        }
    }
}
